package com.wqnmdb.im.netty.handler.impl;

import com.wqnmdb.im.domain.netty.contants.NettyIdentifier;
import com.wqnmdb.im.netty.dispose.NettyDispose;
import com.wqnmdb.im.netty.dispose.impl.NettyDisposeImpl;
import com.wqnmdb.im.netty.handler.BaseHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;


/**
 * netty服务端处理器
 */
@Slf4j
@ChannelHandler.Sharable
public class BusinessHandler extends ChannelInboundHandlerAdapter implements BaseHandler {

    private final NettyDispose nettyDispose = getNettyDispose();

    /**
     * 连接成功 在线人数加1
     */
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        //在线人数统计
        NettyDisposeImpl.sysOnLineNum.incrementAndGet();
    }

    /**
     * 连接断开 在线人数减1
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
        //在线人数统计
        NettyDisposeImpl.sysOnLineNum.decrementAndGet();
    }

    /**
     * 客户端连接服务器会触发此函数
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        nettyDispose.addChannel(ctx);
    }

    /**
     * 客户端终止连接服务器会触发此函数
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //是否有清理标识，没有则清理
        if (!channel.hasAttr(NettyIdentifier.CLEAR_KEY) || !channel.attr(NettyIdentifier.CLEAR_KEY).get()) {
            log.info("客户端终止连接：{}.", ctx.channel().id());
            nettyDispose.remove(ctx);
        } else {
            ctx.close();
        }
    }

    /**
     * 客户端发消息会触发此函数
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        nettyDispose.receiveMsg(ctx, msg);
    }

    /**
     * 发生异常会触发此函数
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("通道：{}.发生了错误，此连接被关闭", ctx.channel().id());
        nettyDispose.remove(ctx);
    }
}
